/*
*	Copyright (C) 2014  Julio Montes, Mario Carrillo
*	
*	Julio Montes e-mail: imc.coder@gmail.com 
*
*	Mario Carrillo e-mail: mario_90ago@live.com.mx
*
*	BSD 3-Clause License
*/

#include "alliance/include/argumentctrl.h"
#include "sdk/include/util.h"
#include <wx/tokenzr.h>

#define STATICTEXTCTRL_ID 2001
#define COMBOBOX_ID 2002
#define TEXTCTRL_ID 2003

namespace alliance
{
    ArgumentCtrl::ArgumentCtrl( wxWindow *parent, wxWindowID id )
        : ToolCtrl( parent, id )
        , m_staticText( NULL )
        , m_comboBox( NULL )
        , m_textCtrl( NULL )
        , m_empty( true )
        , m_fileFilter( wxEmptyString )
        , m_hasDirFiles( false )
        , m_hasProjectFiles( false )
        , m_hasGeneratedFiles( false )
        , m_addToGeneratedFiles( false )
    {

    }

    ArgumentCtrl::~ArgumentCtrl()
    {

    }

    bool ArgumentCtrl::Load( const wxString &key, const sdk::vectorAttributesString &vectorAttributes )
    {
        m_key = key;
        wxColour l_colour( 0, 0, 0 );
        bool l_hasTextCtrl=false;
        bool l_hasComboBox=false;
        bool l_editable=true;
        wxString l_text;
        wxString l_values;
        wxString l_defaultValue;
        for( size_t i=0; i<vectorAttributes.size(); ++i )
        {
            const wxString &name = vectorAttributes[i].name;

            if( 0 == name.Cmp( wxT( "descr" ) ) )
            {
                l_text = vectorAttributes[i].value;
                l_text.Replace( wxT( "\\n" ), wxT( "\n" ) );
            }
            else if( 0 == name.Cmp( wxT( "empty" ) ) )
            {
                l_hasTextCtrl=true;
                m_empty = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "color" ) ) )
            {
                l_colour = sdk::stringToColor( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "filefilter" ) ) )
            {
                l_hasComboBox = true;
                m_fileFilter = vectorAttributes[i].value;
            }
            else if( 0 == name.Cmp( wxT( "hasdirfiles" ) ) )
            {
                l_hasComboBox = true;
                m_hasDirFiles = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "hasprjfiles" ) ) )
            {
                l_hasComboBox = true;
                m_hasProjectFiles = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "hasgenfiles" ) ) )
            {
                l_hasComboBox = true;
                m_hasGeneratedFiles = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "values" ) ) )
            {
                l_hasComboBox = true;
                l_values = vectorAttributes[i].value;
            }
            else if( 0 == name.Cmp( wxT( "defaultvalue" ) ) )
            {
                l_hasTextCtrl=true;
                l_defaultValue = vectorAttributes[i].value;
            }
            else if( 0 == name.Cmp( wxT( "editable" ) ) )
            {
                l_hasTextCtrl=true;
                l_editable = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "addtogenfiles" ) ) )
            {
                l_hasTextCtrl=true;
                m_addToGeneratedFiles = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == name.Cmp( wxT( "type" ) ) )
            {
                m_type = vectorAttributes[i].value;
            }
        }

        if( m_key.IsEmpty() || m_key.Trim().IsEmpty() )
            return false;

        wxBoxSizer *l_boxSizer = new wxBoxSizer( wxHORIZONTAL );
        m_staticText = new wxStaticText( this, STATICTEXTCTRL_ID, l_text );
        m_staticText->SetForegroundColour( l_colour );
        l_boxSizer->Add( m_staticText, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 5 );

        if( l_hasComboBox )
        {
            wxArrayString l_arrayString;
            wxStringTokenizer st( l_values, wxT( "," ), wxTOKEN_STRTOK );
            while( st.HasMoreTokens() )
            {
                l_arrayString.Add( st.GetNextToken() );
            }
            m_comboBox = new wxComboBox( this, COMBOBOX_ID, l_defaultValue, wxDefaultPosition,
                wxDefaultSize, l_arrayString, ( l_editable ? 0 : wxCB_READONLY ) | wxCB_SORT );
            l_boxSizer->Add( m_comboBox, 1, wxLEFT | wxRIGHT, 5 );
        }
        else if( l_hasTextCtrl )
        {
            m_textCtrl = new wxTextCtrl( this, TEXTCTRL_ID, l_defaultValue, wxDefaultPosition,
                wxDefaultSize, ( l_editable ? 0 : wxTE_READONLY ) );
            l_boxSizer->Add( m_textCtrl, 1, wxLEFT | wxRIGHT, 5 );
        }

        SetSizer( l_boxSizer );

        return true;
    }

    bool ArgumentCtrl::IsOk() const
    {
        wxString value;
        if( m_textCtrl != NULL )
        {
            value = m_textCtrl->GetValue();
            if( value.IsEmpty() && !m_empty )
            {
                wxMessageBox( wxT( "The field " ) + m_staticText->GetLabel() +
                    wxT( " is empty" ), wxT( "Error" ), wxICON_ERROR );
                m_textCtrl->SetFocus();
                return false;
            }
            else if( value.Find( _T( '/' ) ) != wxNOT_FOUND || value.Find( _T( '\\' ) ) != wxNOT_FOUND )
            {
                wxMessageBox( wxT( "The field " ) + m_staticText->GetLabel() +
                    wxT( " has an incorrect character" ), wxT( "Error" ), wxICON_ERROR );
                m_textCtrl->SetFocus();
                return false;
            }
        }

        if( m_comboBox != NULL )
        {
            value = m_comboBox->GetValue();
            if( value.IsEmpty() && !m_empty )
            {
                wxMessageBox( wxT( "The field " ) + m_staticText->GetLabel() +
                    wxT( " is empty" ), wxT( "Error" ), wxICON_ERROR );
                m_comboBox->SetFocus();
                return false;
            }
            else if( value.Find( _T( '/' ) ) != wxNOT_FOUND || value.Find( _T( '\\' ) ) != wxNOT_FOUND )
            {
                wxMessageBox( wxT( "The field " ) + m_staticText->GetLabel() +
                    wxT( " has an incorrect character" ), wxT( "Error" ), wxICON_ERROR );
                m_comboBox->SetFocus();
                return false;
            }
        }

        return true;
    }

    wxString ArgumentCtrl::GetText() const
    {
        if( m_textCtrl != NULL )
        {
            return m_textCtrl->GetValue();
        }
        if( m_comboBox != NULL )
        {
            return m_comboBox->GetValue();
        }

        return wxEmptyString;
    }

    void ArgumentCtrl::SetText( const wxString &text )
    {
        if( m_textCtrl != NULL )
        {
            m_textCtrl->SetValue( text );
        }
        else if( m_comboBox != NULL )
        {
            m_comboBox->SetValue( text );
        }
    }

    void ArgumentCtrl::ClearFiles()
    {
        if( NULL == m_comboBox )
        {
            return;
        }

        const wxString value = m_comboBox->GetValue();
        if( !m_comboBox->IsEmpty() ) //deprecated in wx 2.9.5
        {
            m_comboBox->Clear();
        }
        m_comboBox->SetValue( value );
    }

    void ArgumentCtrl::AddFiles( const wxArrayString &arrayFiles )
    {
        if( NULL == m_comboBox || arrayFiles.IsEmpty() )
        {
            return;
        }

        m_comboBox->Append( arrayFiles );
    }

    bool ArgumentCtrl::IsAddedToGeneratedFiles() const
    {
        return m_addToGeneratedFiles;
    }

    bool ArgumentCtrl::HasDirFiles() const
    {
        return m_hasDirFiles;
    }

    bool ArgumentCtrl::HasGeneratedFiles() const
    {
        return m_hasGeneratedFiles;
    }

    bool ArgumentCtrl::HasProjectFiles() const
    {
        return m_hasProjectFiles;
    }

    bool ArgumentCtrl::HasInputField() const
    {
        if( m_comboBox != NULL || m_textCtrl != NULL )
        {
            return true;
        }

        return false;
    }

    const wxString &ArgumentCtrl::GetType() const
    {
        return m_type;
    }
}
